package com.xuelang.pipeline.infrastructure.resource.repository;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xuelang.hiforce.base.tracing.TracingUtils;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.client.resource.dto.EnvironmentQuery;
import com.xuelang.pipeline.domain.resource.Environment;
import com.xuelang.pipeline.domain.resource.repository.EnvironmentRepository;
import com.xuelang.pipeline.infrastructure.resource.converter.EnvironmentToEnvironmentDOConverter;
import com.xuelang.pipeline.infrastructure.resource.dataobject.EnvironmentDO;
import com.xuelang.pipeline.infrastructure.resource.dataobject.SpaceDO;
import com.xuelang.pipeline.infrastructure.resource.mapper.EnvironmentMapper;
import dm.jdbc.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 环境仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class EnvironmentRepositoryImpl implements EnvironmentRepository {

    @Autowired
    EnvironmentMapper environmentMapper;

    @Override
    public PageRecord<Environment> pageList(long currentPage, long pageSize, EnvironmentQuery environmentQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<Environment> page = new Page<>(currentPage, pageSize);
        MPJLambdaWrapper<EnvironmentDO> wrapper = new MPJLambdaWrapper<EnvironmentDO>();
        if (environmentQuery != null) {
            wrapper.selectAll(EnvironmentDO.class)
                    .selectAs(SpaceDO::getName, Environment::getSpaceName)
                    .leftJoin(SpaceDO.class, SpaceDO::getUuid, EnvironmentDO::getSpaceUuid)
                    .like(StrUtil.isNotBlank(environmentQuery.getCode()), EnvironmentDO::getCode, environmentQuery.getCode())
                    .like(StrUtil.isNotBlank(environmentQuery.getName()), EnvironmentDO::getName, environmentQuery.getName())
                    .eq(StrUtil.isNotBlank(environmentQuery.getSpaceUuid()), EnvironmentDO::getSpaceUuid, environmentQuery.getSpaceUuid())
                    .eq(StrUtil.isNotBlank(environmentQuery.getApplicationCode()), EnvironmentDO::getApplicationCode, environmentQuery.getApplicationCode())
                    .eq(StrUtil.isNotBlank(environmentQuery.getUuid()), EnvironmentDO::getUuid, environmentQuery.getUuid())
                    .orderByDesc(SpaceDO::getCreateTime);

        }
        environmentMapper.selectJoinPage(page, Environment.class, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords());
    }

    @Override
    public List<Environment> list(EnvironmentQuery environmentQuery) {
        MPJLambdaWrapper<EnvironmentDO> wrapper = new MPJLambdaWrapper<EnvironmentDO>();
        if (environmentQuery != null) {
            wrapper.selectAll(EnvironmentDO.class)
                    .selectAs(SpaceDO::getName, Environment::getSpaceName)
                    .leftJoin(SpaceDO.class, SpaceDO::getUuid, EnvironmentDO::getSpaceUuid)
                    .like(StrUtil.isNotBlank(environmentQuery.getCode()), EnvironmentDO::getCode, environmentQuery.getCode())
                    .like(StrUtil.isNotBlank(environmentQuery.getName()), EnvironmentDO::getName, environmentQuery.getName())
                    .eq(StrUtil.isNotBlank(environmentQuery.getSpaceUuid()), EnvironmentDO::getSpaceUuid, environmentQuery.getSpaceUuid())
                    .eq(StrUtil.isNotBlank(environmentQuery.getApplicationCode()), EnvironmentDO::getApplicationCode, environmentQuery.getApplicationCode())
                    .eq(StrUtil.isNotBlank(environmentQuery.getUuid()), EnvironmentDO::getUuid, environmentQuery.getUuid())
                    .orderByDesc(SpaceDO::getCreateTime);

        }
        return environmentMapper.selectJoinList(Environment.class, wrapper);
    }
    private String getUserId() {
        String getUserId = TracingUtils.getUserId();
        return StrUtil.isBlank(getUserId) ? "-1" : getUserId;
    }

    @Override
    public Boolean save(Environment environment) {
        environment.setCreatorId(getUserId());
        environment.setUpdaterId(getUserId());
        return environmentMapper.insert(EnvironmentToEnvironmentDOConverter.INSTANCE.environmentToEnvironmentDO(environment)) == 1;
    }

    @Override
    public Boolean update(Environment environment) {
        environment.setUpdaterId(getUserId());
        return environmentMapper.update(
                EnvironmentToEnvironmentDOConverter.INSTANCE.environmentToEnvironmentDO(environment),
                Wrappers.lambdaQuery(EnvironmentDO.class)
                        .eq(EnvironmentDO::getUuid, environment.getUuid())) == 1;
    }

    @Override
    public Boolean delete(String uuid) {
        return environmentMapper.delete(Wrappers.lambdaQuery(EnvironmentDO.class)
                .eq(EnvironmentDO::getUuid, uuid)) == 1;
    }

    @Override
    public Environment query(String uuid) {
        EnvironmentDO environmentDO = environmentMapper.selectOne(Wrappers.lambdaQuery(EnvironmentDO.class).eq(EnvironmentDO::getUuid, uuid));
        return EnvironmentToEnvironmentDOConverter.INSTANCE.environmentDOToEnvironment(environmentDO);
    }

    @Override
    public Boolean existsEnvironmentBySpaceUuid(String spaceUuid) {
        return environmentMapper.exists(Wrappers.lambdaQuery(EnvironmentDO.class).eq(EnvironmentDO::getSpaceUuid, spaceUuid));
    }

    @Override
    public Boolean deleteByApplicationCode(String applicationCode) {
        return environmentMapper.delete(Wrappers.lambdaQuery(EnvironmentDO.class).eq(EnvironmentDO::getApplicationCode, applicationCode)) > 0;
    }

    @Override
    public Boolean existsCode(String applicationCode, String environmentCode) {
        return environmentMapper.exists(Wrappers.lambdaQuery(EnvironmentDO.class)
                .eq(EnvironmentDO::getApplicationCode, applicationCode)
                .eq(EnvironmentDO::getCode, environmentCode));
    }

    @Override
    public Boolean existsName(String applicationCode, String environmentCode, String environmentName) {
        List<EnvironmentDO> environmentDOS = environmentMapper.selectList(Wrappers.lambdaQuery(EnvironmentDO.class)
                .eq(EnvironmentDO::getApplicationCode, applicationCode)
                .eq(EnvironmentDO::getName, environmentName));
        if (ObjectUtil.isEmpty(environmentDOS)) {
            return false;
        }
        return environmentDOS.stream().anyMatch(environmentDO -> !StringUtil.equals(environmentCode, environmentDO.getCode()));
    }
}
